import datetime

class Statistics:
    """
    Klasa u kojoj se drze statistike svih igraca
    """
    
    def __init__(self, users, matches, game_type):
        self.best_users = []
        i = 1

        # najbolji user
        if len(users) > 0:
            self.best_users.append(users[0])
            if game_type == 1:
                max_points = users[0].chess_points
                while len(users) > i and max_points == users[i].chess_points:
                    self.best_users.append(users[i])
                    i = i + 1
            elif game_type == 2:
                max_points = users[0].tf_points
                while len(users) > i and max_points == users[i].tf_points:
                    self.best_users.append(users[i])
                    i = i + 1
            elif game_type == 3:
                max_points = users[0].football_points
                while len(users) > i and max_points == users[i].football_points:
                    self.best_users.append(users[i])
                    i = i + 1
            elif game_type == 4:
                max_points = users[0].basket_points
                while len(users) > i and max_points == users[i].basket_points:
                    self.best_users.append(users[i])
                    i = i + 1
            else:
                raise StandardError("Unknown game type")

        # najgori user
        i = len(users)-2
        self.worst_users = []
        if len(users) > 0:
            self.worst_users.append(users[len(users)-1])
            if game_type == 1:
                min_points = users[len(users)-1].chess_points
                while i>=0 and min_points == users[i].chess_points:
                    self.worst_users.append(users[i])
                    i = i - 1
            elif game_type == 2:
                min_points = users[len(users)-1].tf_points
                while i >= 0 and min_points == users[i].tf_points:
                    self.worst_users.append(users[i])
                    i = i - 1
            elif game_type == 3:
                min_points = users[len(users)-1].football_points
                while i >= 0 and min_points == users[i].football_points:
                    self.worst_users.append(users[i])
                    i = i - 1
            elif game_type == 4:
                min_points = users[len(users)-1].basket_points
                while i >= 0 and min_points == users[i].basket_points:
                    self.worst_users.append(users[i])
                    i = i - 1
            else:
                raise StandardError("Unknown game type")

        # poslednje odigrani mec
        if len(matches) > 0:
            self.last_played_match = matches[0]
        else:
            self.last_played_match = None

        # najcesci saigraci
        teammates = {}
        for match in matches:
            for home_user1 in match.home.all():
                for home_user2 in match.home.all():
                    if home_user1.id >= home_user2.id: continue
                    if (home_user1, home_user2) in teammates:
                        teammates[(home_user1, home_user2)] += 1
                    else:
                        teammates[(home_user1, home_user2)] = 1
            for away_user1 in match.away.all():
                for away_user2 in match.away.all():
                    if away_user1.id >= away_user2.id: continue
                    if (away_user1, away_user2) in teammates:
                        teammates[(away_user1, away_user2)] += 1
                    else:
                        teammates[(away_user1, away_user2)] = 1

        sorted_by_teammates = sorted(teammates.iteritems(), key=lambda obj: obj[1])
        i = len(sorted_by_teammates) - 2
        while i >= 0 and sorted_by_teammates[-1][1] == sorted_by_teammates[i][1]:
            i = i - 1
        self.teammates = sorted_by_teammates[i+1:]

        # najcesci protivnici
        opponents = {}
        for match in matches:
            for home_user1 in match.home.all():
                for away_user2 in match.away.all():
                    if home_user1.id >= away_user2.id: continue
                    if (home_user1, away_user2) in opponents:
                        opponents[(home_user1, away_user2)] += 1
                    else:
                        opponents[(home_user1, away_user2)] = 1
            for away_user1 in match.away.all():
                for home_user2 in match.home.all():
                    if away_user1.id >= home_user2.id: continue
                    if (away_user1, home_user2) in opponents:
                        opponents[(away_user1, home_user2)] += 1
                    else:
                        opponents[(away_user1, home_user2)] = 1

        sorted_by_opponents = sorted(opponents.iteritems(), key=lambda obj: obj[1])
        i = len(sorted_by_opponents) - 2
        while i >= 0 and sorted_by_opponents[-1][1] == sorted_by_opponents[i][1]:
            i = i - 1
        self.opponents = sorted_by_opponents[i+1:]

        # user match agregirane statistike
        self.um_agg = UserMatchesAggregateStatistics(users, matches)

class UserMatchesAggregateStatistics():
    """
    Klasa koja drzi i racuna sve vezano za korisnike i meceve
    """
    
    def __init__(self, users, matches):
        self.user_matches = []
        for user in users:
            self.user_matches.append(UserMatchStatistics(user, matches))
        # ove fancy fore za sortiranje sam pokupio odavde: http://wiki.python.org/moin/HowTo/Sorting#Comparingclasses
        # sorting by played
        i = len(self.user_matches) - 1
        sorted_by_played = sorted(self.user_matches, key = lambda obj: obj.played)
        while i >= 0 and sorted_by_played[-1].played == sorted_by_played[i].played:
            i = i - 1
        self.most_played = sorted_by_played[i+1:]
        
        # sorting by won
        i = len(self.user_matches) - 1
        sorted_by_won = sorted(self.user_matches, key=lambda obj: (obj.won, -obj.played))
        while i >= 0 and sorted_by_won[-1].won == sorted_by_won[i].won and sorted_by_won[-1].played == sorted_by_won[i].played:
            i = i - 1
        self.most_won = sorted_by_won[i+1:]
        
        # sorting by draw
        i = len(self.user_matches) - 1
        sorted_by_draw = sorted(self.user_matches, key=lambda obj: (obj.draw, -obj.played))
        while i >= 0 and sorted_by_draw[-1].draw == sorted_by_draw[i].draw and sorted_by_draw[-1].played == sorted_by_draw[i].played:
            i = i - 1
        self.most_draw = sorted_by_draw[i+1:]
        
        # sorting by lost
        i = len(self.user_matches) - 1
        sorted_by_lost = sorted(self.user_matches, key=lambda obj: (obj.lost, -obj.played))
        while i >= 0 and sorted_by_lost[-1].lost == sorted_by_lost[i].lost and sorted_by_lost[-1].played == sorted_by_lost[i].played:
            i = i - 1
        self.most_lost = sorted_by_lost[i+1:]

        # sorting by won percent
        i = len(self.user_matches) - 1
        sorted_by_won_percent = sorted(self.user_matches, key=lambda obj: (obj.percent_won, obj.played))
        while i >= 0 and sorted_by_won_percent[-1].percent_won == sorted_by_won_percent[i].percent_won and sorted_by_won_percent[-1].played == sorted_by_won_percent[i].played:
            i = i - 1
        self.most_won_percent = sorted_by_won_percent[i+1:]

        # sorting by draw percent
        i = len(self.user_matches) - 1
        sorted_by_draw_percent = sorted(self.user_matches, key=lambda obj: (obj.percent_draw, obj.played))
        while i >= 0 and sorted_by_draw_percent[-1].percent_draw == sorted_by_draw_percent[i].percent_draw and sorted_by_draw_percent[-1].played == sorted_by_draw_percent[i].played:
            i = i - 1
        self.most_draw_percent = sorted_by_draw_percent[i+1:]

        # sorting by lost percent
        i = len(self.user_matches) - 1
        sorted_by_lost_percent = sorted(self.user_matches, key=lambda obj: (obj.percent_lost, obj.played))
        while i >= 0 and sorted_by_lost_percent[-1].percent_lost == sorted_by_lost_percent[i].percent_lost and sorted_by_lost_percent[-1].played == sorted_by_lost_percent[i].played:
            i = i - 1
        self.most_lost_percent = sorted_by_lost_percent[i+1:]

class UserMatchStatistics():
    """
    Klasa koja drzi podatke za meceve jednog korisnika
    """
    
    def __init__(self, user, matches):
        self.user = user
        self.played = 0
        self.won = 0
        self.draw = 0
        self.lost = 0
        for match in matches:
            for user_iter in match.home.all():
                if user.id == user_iter.id:
                    self.played += 1
                    if match.winner == 1:
                        self.won += 1
                    elif match.winner == 2:
                        self.draw += 1
                    else:
                        self.lost += 1
            for user_iter in match.away.all():
                if user.id == user_iter.id:
                    self.played += 1
                    if match.winner == 3:
                        self.won += 1
                    elif match.winner == 2:
                        self.draw += 1
                    else:
                        self.lost += 1

        self.percent_won = 100 * self.won/float(self.played) if self.played > 0 else 0.0
        self.percent_draw = 100 * self.draw/float(self.played) if self.played > 0 else 0.0
        self.percent_lost = 100 * self.lost/float(self.played) if self.played > 0 else 0.0